package com.nuoniu.sibanyun.service.production.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.entity.erp.ErpNumberSet;
import com.nuoniu.sibanyun.entity.inOut.VInOutAllocationDetail;
import com.nuoniu.sibanyun.entity.inOut.VInOutAllocationMain;
import com.nuoniu.sibanyun.entity.production.VProcedurePriceDetail;
import com.nuoniu.sibanyun.entity.production.VProcedurePriceMain;
import com.nuoniu.sibanyun.entity.production.VProductionFinishMain;
import com.nuoniu.sibanyun.mapper.erp.ErpNumberSetMapper;
import com.nuoniu.sibanyun.mapper.production.VProcedurePriceMainMapper;
import com.nuoniu.sibanyun.service.crm.ICrmGoodsService;
import com.nuoniu.sibanyun.service.erp.IErpAccountService;
import com.nuoniu.sibanyun.service.erp.IErpNumberSetService;
import com.nuoniu.sibanyun.service.production.IVProcedurePriceDetailService;
import com.nuoniu.sibanyun.service.production.IVProcedurePriceMainService;
import com.nuoniu.sibanyun.service.utils.ErpUtils;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 工序工价主表 服务实现类
 * </p>
 *
 * @author 白强
 * @since 2021-08-14
 */
@Service
public class VProcedurePriceMainServiceImpl extends ServiceImpl<VProcedurePriceMainMapper, VProcedurePriceMain> implements IVProcedurePriceMainService {

    @Autowired
    private IErpAccountService accountService;
    @Autowired
    private ErpNumberSetMapper numberSetMapper;
    @Autowired
    private IErpNumberSetService numberSetService;
    @Autowired
    private IVProcedurePriceDetailService procedurePriceDetailService;
    @Autowired
    private ICrmGoodsService crmGoodsService;

    @Override
    public void saveOrder(VProcedurePriceMain vProcedurePriceMain) {
        LocalDateTime now = LocalDateTime.now();
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = accountService.getCurrentAccountId();
        List<VProcedurePriceDetail> orderDetailList = vProcedurePriceMain.getOrderDetailList();
        if( null == orderDetailList || orderDetailList.size() == 0)throw new NuoNiuException("明细不能为空");
        orderDetailList.stream().forEach(item->{
            Integer wagesType = item.getWagesType();

            if(1 == wagesType){
                if( null == item.getQualifiedPrice() || null == item.getUnqualifiedPrice() || null == item.getReworkPrice() || null == item.getScrapPrice()){
                    throw new NuoNiuException("请填写计件价格");
                }
            }else if(2 == wagesType) {
                BigDecimal workHourPrice = item.getWorkHourPrice();
                if (null == workHourPrice)throw new NuoNiuException("请填报工时价格");
            }
        });

        Long mainId = vProcedurePriceMain.getId();
        if (null == mainId){
            String code = getCode();
            if(code == null) {
                throw new NuoNiuException("单据编号已上限");
            }
            boolean isHaveId = orderDetailList.stream().anyMatch(f -> null != f.getId());
            if(isHaveId)throw new NuoNiuException("单据明细错误：不能新增已经存在的明细记录");
            vProcedurePriceMain.setVoucherState(-1);
            vProcedurePriceMain.setVoucherCode(code);
            vProcedurePriceMain.setAccountId(currentAccountId);
            vProcedurePriceMain.setCompanyId(userInfo.getCompanyId());
            vProcedurePriceMain.setCreateUserId(userInfo.getUserId());
            vProcedurePriceMain.setCreateUserName(userInfo.getRealName());
            vProcedurePriceMain.setCreateDate(now);

        }else{
            //校验详情（详情不能有其他单据的明细ID）
            boolean isHaveErrorId = orderDetailList.stream().anyMatch(f -> null != f.getOrderId() && !mainId.toString().equals(f.getOrderId().toString()));
            if(isHaveErrorId)throw new NuoNiuException("单据明细错误：不能修改其他单据的明细记录");
            VProcedurePriceMain oldVProcedurePriceMain = this.getById(mainId);
            Integer voucherState = oldVProcedurePriceMain.getVoucherState();
            if(voucherState != null && voucherState > 0) {
                throw new NuoNiuException("已审核,不能修改");
            }
            /**************  修改权限 *******************/
            if(!crmGoodsService.isHaveOperationRight(oldVProcedurePriceMain.getCreateUserId().longValue())){
                throw new NuoNiuException("你没有权限操作该记录");
            }
        }


        boolean result = this.saveOrUpdate(vProcedurePriceMain);

        if(result) {
            List<Long> detailIds = new ArrayList<>();
            orderDetailList.forEach(p -> {
                p.setOrderId(vProcedurePriceMain.getId().intValue());
                p.setCompanyId(userInfo.getCompanyId());
                p.setAccountId(vProcedurePriceMain.getAccountId());
                if(p.getId() != null) {
                    detailIds.add(p.getId());
                }
            });
            //删除明细
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.eq("order_id", mainId);
            if(detailIds.size() > 0) {
                wrapper.notIn("id", detailIds);
                procedurePriceDetailService.remove(wrapper);
            }else {
                procedurePriceDetailService.remove(wrapper);
            }
            //保存单据明细表
            procedurePriceDetailService.saveOrUpdateBatch(orderDetailList);
        }
    }

    @Override
    public String getCode() {
        Integer currentAccountId = accountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();
        ErpNumberSet numberSet = numberSetMapper.getByCode("ProcedurePrice", userInfo.getCompanyId(), currentAccountId);
        String dateStr = numberSet.getMedian() == 1 ? "%Y-%m-%d" : "%Y-%m";
        String code = baseMapper.getNewestCode(userInfo.getCompanyId(), dateStr);
        return numberSetService.getCode(numberSet, code);
    }

    @Override
    public void deleteById(Long id) {
        UserInfo userInfo = UserThreadLocal.get();
        VProcedurePriceMain procedurePriceMain = getById(id);
        if ( null == procedurePriceMain)throw new NuoNiuException("参数错误");
        if(!crmGoodsService.isHaveOperationRight(procedurePriceMain.getCreateUserId().longValue())){
            throw new NuoNiuException("你没有权限操作该记录");
        }
        removeById(id);
    }

    @Override
    public void submit(Long id, Integer status) {
        if(null == id || null == status || (null != status && (status > 0 || status < -1 )))throw new NuoNiuException("参数错误");
        UserInfo userInfo = UserThreadLocal.get();
        VProcedurePriceMain main = this.getById(id);
        if( null == main)throw new NuoNiuException("记录不存在");
        //校验状态
        Integer voucherState = main.getVoucherState();
        /**  统一校验 提交状态 */
        ErpUtils.checkSubmitStatus(voucherState,status);
        //提交
        main.setVoucherState(status);
        main.setSubmitDate(LocalDateTime.now());
        main.setSubmitUserId(userInfo.getUserId());
        main.setSubmitUserName(userInfo.getRealName());
        this.updateById(main);
    }

    @Override
    public void examine(Long id, Integer status) {
        if (!(0 == status || 1 == status))throw new NuoNiuException("参数错误");
        UserInfo userInfo = UserThreadLocal.get();
        VProcedurePriceMain procedurePriceMain = getById(id);
        if (null == procedurePriceMain)throw new NuoNiuException("参数错误");
        Integer voucherState = procedurePriceMain.getVoucherState();
        Boolean oldEnableState = procedurePriceMain.getEnableState();
        if ( 0 == status){
            if (oldEnableState)throw new NuoNiuException("已经启用，不能弃审");
        }
        /**  统一校验 提交状态 */
        ErpUtils.checkExamineStatus(voucherState,status,null);
        procedurePriceMain.setVoucherState(status);
        procedurePriceMain.setReviewerUserId(userInfo.getUserId());
        procedurePriceMain.setReviewerUserName(userInfo.getRealName());
        procedurePriceMain.setReviewerDate(LocalDateTime.now());
        updateById(procedurePriceMain);

    }

    @Override
    public void changeEnableState(Long id, Boolean enableState) {
        if (null == enableState)throw new NuoNiuException("参数错误");
        VProcedurePriceMain procedurePriceMain = getById(id);
        if (null == procedurePriceMain)throw new NuoNiuException("参数错误");
        Boolean oldEnableState = procedurePriceMain.getEnableState();
        Integer voucherState = procedurePriceMain.getVoucherState();
        if(enableState){
            if(oldEnableState)throw new NuoNiuException("已经启用");
            if(0 == voucherState )throw new NuoNiuException("未审核，不能启用");
            //校验 是否已经启用相同的
            boolean checkEnableState = checkEnableState(procedurePriceMain.getProcessRouteId(), procedurePriceMain.getInventoryId());
            if (checkEnableState)throw new NuoNiuException("有相同工序价格设置已经启用，请先关闭");
        }else{
            if(!oldEnableState)throw new NuoNiuException("未启用");
        }

        procedurePriceMain.setEnableState(enableState);
        updateById(procedurePriceMain);
    }

    @Override
    public boolean checkEnableState(Integer processRouteId, Integer inventoryId) {
        UserInfo userInfo = UserThreadLocal.get();
        boolean b = baseMapper.checkEnableState(userInfo.getCompanyId(), processRouteId, inventoryId);
        return b;
    }
}
